################################################################################
#函数raprt()可以建立一个决策树，并且可以选择最小误差的预测
################################################################################

data("bodyfat", package = "TH.data")
dim(bodyfat)
attributes(bodyfat)
bodyfat[1:5,]
#将数据集分为训练集和测试集，并根据训练集建立决策树。
set.seed(1234)
ind <- sample(2, nrow(bodyfat), replace=TRUE, prob=c(0.7, 0.3))
bodyfat.train <- bodyfat[ind==1,]
bodyfat.test <- bodyfat[ind==2,]

library(rpart)
# 编写公式myFormula
myFormula <- DEXfat ~ age + waistcirc + hipcirc + elbowbreadth + kneebreadth
# 训练决策树
bodyfat_rpart <- rpart(myFormula, data = bodyfat.train,
                        control = rpart.control(minsplit = 10))
# 画决策树
plot(bodyfat_rpart)
# 添加文本标签
text(bodyfat_rpart, use.n=T)

#选择预测误差最小值的预测树，从而优化模型。
opt <- which.min(bodyfat_rpart$cptable[,"xerror"])
cp <- bodyfat_rpart$cptable[opt, "CP"]
bodyfat_prune <- prune(bodyfat_rpart, cp = cp)
plot(bodyfat_rpart)
text(bodyfat_rpart, use.n=T)

#优化模型后，就是将hipcirc<99.5这个分层给去掉了
#下面的代码中，使用函数abline()绘制一条斜线。
#一个好的模型的预测值应该是约接近真实值越好，也就是说大部分的点应该落在斜线上面或者在斜线附近。
# 根据测试集预测
DEXfat_pred <- predict(bodyfat_prune, newdata=bodyfat.test)
# 预测值的极值
xlim <- range(bodyfat$DEXfat)
plot(DEXfat_pred ~ DEXfat, data=bodyfat.test, xlab="Observed",
      ylab="Predicted", ylim=xlim, xlim=xlim)
abline(a=0, b=1)
